home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Apache 1.0 / src / http_config.c < prev    next >
Text File  |  1995-12-04  |  21KB  |  751 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55. /*
  56.  * http_config.c: once was auxillary functions for reading httpd's config
  57.  * file and converting filenames into a namespace
  58.  *
  59.  * Rob McCool 
  60.  * 
  61.  * Wall-to-wall rewrite for Shambhala... commands which are part of the
  62.  * server core can now be found next door in "http_core.c".  Now contains
  63.  * general command loop, and functions which do bookkeeping for the new
  64.  * Shambhala config stuff (modules and configuration vectors).
  65.  *
  66.  * rst
  67.  *
  68.  */
  69.  
  70. #define CORE_PRIVATE
  71.  
  72. #include "httpd.h"
  73. #include "http_config.h"
  74. #include "http_core.h"
  75. #include "http_log.h"        /* for errors in parse_htaccess */
  76. #include "http_request.h"    /* for default_handler (see invoke_handler) */
  77. #include "http_conf_globals.h"    /* Sigh... */
  78.  
  79. /****************************************************************
  80.  *
  81.  * We begin with the functions which deal with the linked list
  82.  * of modules which control just about all of server operation in
  83.  * Shambhala.
  84.  */
  85.  
  86. static int num_modules = 0;    
  87. module *top_module = NULL;
  88.     
  89. typedef int (*handler)(request_rec *);
  90. typedef void *(*maker)(pool *);
  91. typedef void *(*dir_maker)(pool *, char *);
  92. typedef void *(*merger)(pool *, void *, void *);    
  93.  
  94. /* Dealing with config vectors.  These are associated with per-directory,
  95.  * per-server, and per-request configuration, and have a void* pointer for
  96.  * each modules.  The nature of the structure pointed to is private to the
  97.  * module in question... the core doesn't (and can't) know.  However, there
  98.  * are defined interfaces which allow it to create instances of its private
  99.  * per-directory and per-server structures, and to merge the per-directory
  100.  * structures of a directory and its subdirectory (producing a new one in
  101.  * which the defaults applying to the base directory have been properly
  102.  * overridden).
  103.  */
  104.  
  105. void *    
  106. get_module_config (void *conf_vector, module *m)
  107. {
  108.    void **confv = (void**)conf_vector;
  109.    return confv[m->module_index];
  110. }
  111.  
  112. void
  113. set_module_config (void *conf_vector, module *m, void *val)
  114. {
  115.    void **confv = (void**)conf_vector;
  116.    confv[m->module_index] = val;
  117. }
  118.  
  119. void *
  120. create_empty_config (pool *p)
  121. {
  122.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * num_modules);
  123.    return (void *)conf_vector;
  124. }
  125.  
  126. void *
  127. create_default_per_dir_config (pool *p)
  128. {
  129.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (num_modules+DYNAMIC_MODULE_LIMIT));
  130.    module *modp;
  131.  
  132.    for (modp = top_module; modp; modp = modp->next) {
  133.        dir_maker df = modp->create_dir_config;
  134.  
  135.        if (df) conf_vector[modp->module_index] = (*df)(p, NULL);
  136.    }
  137.  
  138.    return (void*)conf_vector;
  139. }
  140.  
  141. void *
  142. merge_per_dir_configs (pool *p, void *base, void *new)
  143. {
  144.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * num_modules);
  145.    void **base_vector = (void **) base;
  146.    void **new_vector = (void **) new;
  147.    module *modp;
  148.  
  149.    for (modp = top_module; modp; modp = modp->next) {
  150.        merger df = modp->merge_dir_config;
  151.        int i = modp->module_index;
  152.  
  153.        if (df && new_vector[i])
  154.        conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
  155.        else
  156.        conf_vector[i] = new_vector[i]? new_vector[i] : base_vector[i];
  157.    }
  158.  
  159.    return (void*)conf_vector;
  160. }
  161.  
  162. void *
  163. create_server_config (pool *p, server_rec *s)
  164. {
  165.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (num_modules+DYNAMIC_MODULE_LIMIT));
  166.    module *modp;
  167.  
  168.    for (modp = top_module; modp; modp = modp->next) {
  169.        if (modp->create_server_config)
  170.        conf_vector[modp->module_index]=(*modp->create_server_config)(p,s);
  171.    }
  172.  
  173.    return (void*)conf_vector;
  174. }
  175.  
  176. void merge_server_configs (pool *p, void *base, void *virt)
  177. {
  178.     /* Can reuse the 'virt' vector for the spine of it, since we don't
  179.      * have to deal with the moral equivalent of .htaccess files here...
  180.      */
  181.  
  182.     void **base_vector = (void **)base;
  183.     void **virt_vector = (void **)virt;
  184.     module *modp;
  185.     
  186.     for (modp = top_module; modp; modp = modp->next) {
  187.     merger df = modp->merge_server_config;
  188.     int i = modp->module_index;
  189.  
  190.     if (!virt_vector[i])
  191.         virt_vector[i] = base_vector[i];
  192.     else if (df)
  193.         virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
  194.     }
  195. }
  196.  
  197. void *create_connection_config (pool *p) {
  198.     return create_empty_config (p);
  199. }
  200.  
  201. void *create_request_config (pool *p) {
  202.     return create_empty_config (p);
  203. }
  204.  
  205. void *create_per_dir_config (pool *p) {
  206.     return create_empty_config (p);
  207. }
  208.  
  209. /****************************************************************
  210.  *
  211.  * Dispatch through the modules to find handlers for various phases
  212.  * of request handling.  These are invoked by http_request.c to actually
  213.  * do the dirty work of slogging through the module structures.
  214.  */
  215.  
  216. int
  217. run_method (request_rec *r, int offset, int run_all)
  218. {
  219.    module *modp;
  220.    for (modp = top_module; modp; modp = modp->next) {
  221.        handler mod_handler = *(handler *)(offset + (char *)(modp));
  222.  
  223.        if (mod_handler) {
  224.        int result = (*mod_handler)(r);
  225.  
  226.        if (result != DECLINED && (!run_all || result != OK))
  227.            return result;
  228.        }
  229.    }
  230.  
  231.    return run_all ? OK : DECLINED;
  232. }
  233.  
  234. int translate_name(request_rec *r) {
  235.    return run_method (r, XtOffsetOf (module, translate_handler), 0);
  236. }
  237.  
  238. int check_access(request_rec *r) {
  239.    return run_method (r, XtOffsetOf (module, access_checker), 1);
  240. }
  241.  
  242. int find_types (request_rec *r) {
  243.    return run_method (r, XtOffsetOf (module, type_checker), 0);
  244. }
  245.  
  246. int run_fixups (request_rec *r) {
  247.    return run_method (r, XtOffsetOf (module, fixer_upper), 1);
  248. }
  249.  
  250. int log_transaction (request_rec *r) {
  251.    return run_method (r, XtOffsetOf (module, logger), 1);
  252. }
  253.  
  254. /* Auth stuff --- anything that defines one of these will presumably
  255.  * want to define something for the other.  Note that check_auth is
  256.  * separate from check_access to make catching some config errors easier.
  257.  */
  258.  
  259. int check_user_id (request_rec *r) {
  260.    return run_method (r, XtOffsetOf (module, check_user_id), 0);
  261. }
  262.  
  263. int check_auth (request_rec *r) {
  264.    return run_method (r, XtOffsetOf (module, auth_checker), 0);
  265. }
  266.  
  267. /*
  268.  * This should really do multiple passes, choosing wildcards last,
  269.  * which would allow us to declare default_handler as a wildcard on
  270.  * core_module.  Close enough for now...
  271.  */
  272.  
  273. int invoke_handler (request_rec *r)
  274. {
  275.    module *modp;
  276.    handler_rec *handp;
  277.    char *content_type = r->content_type ? r->content_type : default_type (r);
  278.   
  279.    /* Pass one --- direct matches */
  280.    
  281.    for (modp = top_module; modp; modp = modp->next) 
  282.    {
  283.        if (!modp->handlers) continue;
  284.        
  285.        for (handp = modp->handlers; handp->content_type; ++handp) {
  286.        if (!strcasecmp (content_type, handp->content_type)) {
  287.            int result = (*handp->handler)(r);
  288.  
  289.            if (result != DECLINED) return result;
  290.        }
  291.        }
  292.    }
  293.    
  294.    /* Pass two --- wildcard matches */
  295.    
  296.    for (modp = top_module; modp; modp = modp->next) 
  297.    {
  298.        if (!modp->handlers) continue;
  299.        
  300.        for (handp = modp->handlers; handp->content_type; ++handp) {
  301.        char *starp = strchr (handp->content_type, '*');
  302.        int len;
  303.  
  304.        if (!starp) continue;
  305.  
  306.        len = starp - handp->content_type;
  307.        
  308.        if (!len || !strncasecmp (content_type, handp->content_type, len))
  309.        {
  310.            int result = (*handp->handler)(r);
  311.  
  312.            if (result != DECLINED) return result;
  313.        }
  314.        }
  315.    }
  316.    
  317.    return NOT_IMPLEMENTED;
  318. }
  319.  
  320. /* One-time setup for precompiled modules --- NOT to be done on restart */
  321.  
  322. void add_module (module *m)
  323. {
  324.     /* This could be called from an AddModule httpd.conf command,
  325.      * after the file has been linked and the module structure within it
  326.      * teased out...
  327.      */
  328.  
  329.     m->next = top_module;
  330.     top_module = m;
  331.     m->module_index = num_modules++;
  332. }
  333.  
  334. void setup_prelinked_modules ()
  335. {
  336.     extern module *prelinked_modules[];
  337.     module **m = prelinked_modules;
  338.  
  339.     while (*m) {
  340.         add_module (*m);
  341.     ++m;
  342.     }
  343. }
  344.  
  345. /*****************************************************************
  346.  *
  347.  * Resource, access, and .htaccess config files now parsed by a common
  348.  * command loop.
  349.  *
  350.  * Let's begin with the basics; parsing the line and
  351.  * invoking the function...
  352.  */
  353.  
  354. char *invoke_cmd(command_rec *cmd, cmd_parms *parms, void *mconfig, char *args)
  355. {
  356.     char *w, *w2, *errmsg;
  357.  
  358.     if ((parms->override & cmd->req_override) == 0)
  359.         return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);
  360.     
  361.     parms->info = cmd->cmd_data;
  362.     
  363.     switch (cmd->args_how) {
  364.     case RAW_ARGS:
  365.         return (*cmd->func) (parms, mconfig, args);
  366.  
  367.     case NO_ARGS:
  368.     if (*args != 0)
  369.         return pstrcat (parms->pool, cmd->name, " takes no arguments",
  370.                 NULL);
  371.  
  372.     return (*cmd->func) (parms, mconfig);
  373.     
  374.     case TAKE1:
  375.     w = getword_conf (parms->pool, &args);
  376.     
  377.     if (*w == '\0' || *args != 0) 
  378.         return pstrcat (parms->pool, cmd->name, " takes one argument",
  379.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  380.  
  381.     return (*cmd->func) (parms, mconfig, w);
  382.     
  383.     case TAKE2:
  384.  
  385.     w = getword_conf (parms->pool, &args);
  386.     w2 = getword_conf (parms->pool, &args);
  387.     
  388.     if (*w == '\0' || *w2 == '\0' || *args != 0) 
  389.         return pstrcat (parms->pool, cmd->name, " takes two arguments",
  390.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  391.  
  392.     return (*cmd->func) (parms, mconfig, w, w2);
  393.     
  394.     case ITERATE:
  395.  
  396.     while (*(w = getword_conf (parms->pool, &args)) != '\0')
  397.         if ((errmsg = (*cmd->func) (parms, mconfig, w)))
  398.             return errmsg;
  399.  
  400.     return NULL;
  401.     
  402.     case ITERATE2:
  403.  
  404.     w = getword_conf (parms->pool, &args);
  405.     
  406.     if (*w == '\0' || *args == 0) 
  407.         return pstrcat(parms->pool, cmd->name,
  408.                " requires at least two arguments",
  409.                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  410.       
  411.  
  412.     while (*(w2 = getword_conf (parms->pool, &args)) != '\0')
  413.         if ((errmsg = (*cmd->func) (parms, mconfig, w, w2)))
  414.             return errmsg;
  415.  
  416.     return NULL;
  417.     
  418.     case FLAG:
  419.  
  420.     w = getword_conf (parms->pool, &args);
  421.  
  422.     if (*w == '\0' || ((!strcasecmp(w, "on")) && (!strcasecmp (w, "off"))))
  423.         return pstrcat (parms->pool, cmd->name, " must be On or Off",
  424.                 NULL);
  425.  
  426.     return (*cmd->func) (parms, mconfig, strcasecmp (w, "off"));
  427.  
  428.     default:
  429.  
  430.     return pstrcat (parms->pool, cmd->name,
  431.             " is improperly configured internally (server bug)",
  432.             NULL);
  433.     }
  434. }
  435.  
  436. command_rec *find_command (char *name, command_rec *cmds)
  437. {
  438.     while (cmds->name) 
  439.         if (!strcasecmp (name, cmds->name))
  440.         return cmds;
  441.     else
  442.         ++cmds;
  443.  
  444.     return NULL;
  445. }
  446.     
  447. command_rec *find_command_in_modules (char *cmd_name, module **mod)
  448. {
  449.    command_rec *cmdp;
  450.    module *modp;
  451.  
  452.    for (modp = top_module; modp; modp = modp->next) 
  453.        if (modp->cmds && (cmdp = find_command (cmd_name, modp->cmds))) {
  454.        *mod = modp;
  455.        return cmdp;
  456.        }
  457.  
  458.    return NULL;
  459. }
  460.  
  461. char *handle_command (cmd_parms *parms, void *config, char *l)
  462. {
  463.     char *args, *cmd_name;
  464.     command_rec *cmd;
  465.     module *mod;
  466.  
  467.     ++parms->config_line;
  468.     if((l[0] == '#') || (!l[0])) return NULL;
  469.     
  470.     args = l;
  471.     cmd_name = getword_conf (parms->temp_pool, &args);
  472.     if (*cmd_name == '\0') return NULL;
  473.     
  474.     if (!(cmd = find_command_in_modules (cmd_name, &mod))) {
  475.     return pstrcat (parms->pool, "Invalid command ", cmd_name, NULL);
  476.     }
  477.     else {
  478.     void *mconfig = get_module_config (config, mod);
  479.     void *sconfig = get_module_config (parms->server->module_config, mod);
  480.           
  481.     if (!mconfig && mod->create_dir_config) {
  482.         mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
  483.         set_module_config (config, mod, mconfig);
  484.     }
  485.         
  486.     if (!sconfig && mod->create_server_config) {
  487.         sconfig = (*mod->create_server_config)(parms->pool, parms->server);
  488.         set_module_config (parms->server->module_config, mod, sconfig);
  489.     }
  490.     
  491.     return invoke_cmd (cmd, parms, mconfig, args);
  492.     }
  493. }
  494.  
  495. char *srm_command_loop (cmd_parms *parms, void *config)
  496. {
  497.     char l[MAX_STRING_LEN];
  498.     
  499.     while (!(cfg_getline (l, MAX_STRING_LEN, parms->infile))) {
  500.     char *errmsg = handle_command (parms, config, l);
  501.     if (errmsg) return errmsg;
  502.     }
  503.  
  504.     return NULL;
  505. }
  506.  
  507. /*
  508.  * Generic command functions...
  509.  */
  510.  
  511. char *set_string_slot (cmd_parms *cmd, char *struct_ptr, char *arg)
  512. {
  513.     /* This one's pretty generic... */
  514.   
  515.     int offset = (int)cmd->info; 
  516.     *(char **)(struct_ptr + offset) = pstrdup (cmd->pool, arg);
  517.     return NULL;
  518. }
  519.  
  520. /*****************************************************************
  521.  *
  522.  * Reading whole config files...
  523.  */
  524.  
  525. cmd_parms default_parms = { NULL, 0, -1, NULL, 0, NULL, NULL, NULL, NULL };
  526.  
  527. char *server_root_relative (pool *p, char *file)
  528. {
  529.     if (file[0] == '/') return file;
  530.     return make_full_path (p, server_root, file);
  531. }
  532.  
  533. void process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
  534. {
  535.     FILE *cfg;
  536.     char *errmsg;
  537.     cmd_parms parms;
  538.     
  539.     fname = server_root_relative (p, fname);
  540.     
  541.     /* GCC's initialization extensions are soooo nice here... */
  542.     
  543.     parms = default_parms;
  544.     parms.config_file = fname;
  545.     parms.pool = p;
  546.     parms.temp_pool = ptemp;
  547.     parms.server = s;
  548.     parms.override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
  549.     
  550.     if(!(cfg = fopen(fname, "r"))) {
  551.         fprintf(stderr,"httpd: could not open document config file %s\n",
  552.                 fname);
  553.         perror("fopen");
  554.         exit(1);
  555.     } 
  556.  
  557.     parms.infile = cfg;
  558.     
  559.     errmsg = srm_command_loop (&parms, s->lookup_defaults);
  560.     
  561.     if (errmsg) {
  562.         fprintf (stderr, "Syntax error on line %d of %s:\n",
  563.          parms.config_line, fname);
  564.     fprintf (stderr, "%s\n", errmsg);
  565.     exit(1);
  566.     }
  567.     
  568.     fclose(cfg);
  569. }
  570.  
  571.  
  572. int parse_htaccess(void **result, request_rec *r, int override,
  573.            char *d, char *filename)
  574. {
  575.     FILE *f;
  576.     cmd_parms parms;
  577.     char *errmsg;
  578.  
  579.     parms = default_parms;
  580.     parms.override = override;
  581.     parms.pool = r->pool;
  582.     parms.temp_pool = r->pool;
  583.     parms.server = r->server;
  584.     parms.path = d;
  585.  
  586.     if((f=pfopen(r->pool, filename, "r"))) {
  587.         void *dc = create_per_dir_config (r->pool);
  588.     
  589.         parms.infile = f;
  590.     parms.config_file = filename;
  591.  
  592.     errmsg = srm_command_loop (&parms, dc);
  593.     
  594.         pfclose(r->pool, f);
  595.  
  596.     if (errmsg) {
  597.         log_reason (errmsg, filename, r);
  598.         return SERVER_ERROR;
  599.     }
  600.     
  601.     *result = dc;
  602.     return OK;
  603.     }
  604.     else
  605.         return OK;
  606. }
  607.  
  608. /*****************************************************************
  609.  *
  610.  * Virtual host stuff; note that the commands that invoke this stuff
  611.  * are with the command table in http_core.c.
  612.  */
  613.  
  614. server_rec *init_virtual_host (pool *p, char *hostname)
  615. {
  616.     server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
  617.  
  618. #ifdef RLIMIT_NOFILE
  619.     struct rlimit limits;
  620.  
  621.     getrlimit ( RLIMIT_NOFILE, &limits );
  622.     if ( limits.rlim_cur < limits.rlim_max ) {
  623.       limits.rlim_cur += 2;
  624.       if ( setrlimit ( RLIMIT_NOFILE, &limits ) < 0 )
  625.     fprintf (stderr, "Cannot exceed hard limit for open files");
  626.     }
  627. #endif
  628.  
  629.     s->port = 0;
  630.     s->server_admin = NULL;
  631.     s->server_hostname = NULL; 
  632.     s->error_fname = NULL;
  633.     s->srm_confname = NULL;
  634.     s->access_confname = NULL;
  635.     s->timeout = 0;
  636.     s->do_rfc931 = 0;
  637.     s->host_addr.s_addr = get_virthost_addr (hostname, 0);
  638.     s->next = NULL;
  639.  
  640.     s->module_config = create_empty_config (p);
  641.     s->lookup_defaults = create_per_dir_config (p);
  642.     
  643.     return s;
  644. }
  645.  
  646. int is_virtual_server (server_rec *s)
  647. {
  648.     return s->host_addr.s_addr != htonl (INADDR_ANY);
  649. }
  650.  
  651. void fixup_virtual_hosts (pool *p, server_rec *main_server)
  652. {
  653.     server_rec *virt;
  654.  
  655.     for (virt = main_server->next; virt; virt = virt->next) {
  656.     merge_server_configs (p, main_server->module_config,
  657.                   virt->module_config);
  658.     
  659.     virt->lookup_defaults =
  660.         merge_per_dir_configs (p, main_server->lookup_defaults,
  661.                    virt->lookup_defaults);
  662.  
  663.     if (virt->port == 0)
  664.         virt->port = main_server->port;
  665.  
  666.     if (virt->server_admin == NULL)
  667.         virt->server_admin = main_server->server_admin;
  668.  
  669.     if (virt->srm_confname == NULL)
  670.         virt->srm_confname = main_server->srm_confname;
  671.  
  672.     if (virt->access_confname == NULL)
  673.         virt->access_confname = main_server->access_confname;
  674.  
  675.     if (virt->timeout == 0)
  676.         virt->timeout = main_server->timeout;
  677.  
  678.     if (virt->do_rfc931 == 0)
  679.         virt->do_rfc931 = main_server->do_rfc931;
  680.     }
  681. }
  682.  
  683. /*****************************************************************
  684.  *
  685.  * Getting *everything* configured... 
  686.  */
  687.  
  688. void init_config_globals (pool *p)
  689. {
  690.     /* ServerRoot, server_confname set in httpd.c */
  691.     
  692.     standalone = 1;
  693.     user_name = DEFAULT_USER;
  694.     user_id = uname2id(DEFAULT_USER);
  695.     group_id = gname2id(DEFAULT_GROUP);
  696.     daemons_to_start = DEFAULT_START_DAEMON;
  697.     daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
  698.     daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
  699.     daemons_limit = DEFAULT_SERVER_LIMIT;
  700.     pid_fname = DEFAULT_PIDLOG;
  701.     max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
  702.     bind_address.s_addr = htonl(INADDR_ANY);
  703. }
  704.  
  705. server_rec *init_server_config(pool *p)
  706. {
  707.     server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
  708.  
  709.     s->port = DEFAULT_PORT;
  710.     s->server_admin = DEFAULT_ADMIN;
  711.     s->server_hostname = NULL; 
  712.     s->error_fname = DEFAULT_ERRORLOG;
  713.     s->srm_confname = RESOURCE_CONFIG_FILE;
  714.     s->access_confname = ACCESS_CONFIG_FILE;
  715.     s->timeout = DEFAULT_TIMEOUT;
  716.     s->do_rfc931 = DEFAULT_RFC931;
  717.     s->next = NULL;
  718.     s->host_addr.s_addr = htonl (INADDR_ANY); /* NOT virtual host;
  719.                            * don't match any real network
  720.                            * interface.
  721.                            */
  722.  
  723.     s->module_config = create_server_config (p, s);
  724.     s->lookup_defaults = create_default_per_dir_config (p);
  725.     
  726.     return s;
  727. }
  728.  
  729. server_rec *read_config(pool *p, pool *ptemp, char *confname)
  730. {
  731.     server_rec *s = init_server_config(p);
  732.     module *m;
  733.     
  734.     init_config_globals(p);
  735.     
  736.     /* All server-wide config files now have the SAME syntax... */
  737.     
  738.     process_resource_config (s, confname, p, ptemp);
  739.     process_resource_config (s, s->srm_confname, p, ptemp);
  740.     process_resource_config (s, s->access_confname, p, ptemp);
  741.     
  742.     fixup_virtual_hosts (p, s);
  743.     
  744.     for (m = top_module; m; m = m->next)
  745.         if (m->init)
  746.         (*m->init) (s, p);
  747.     
  748.     return s;
  749. }
  750.  
  751.